package org.ala.tiktools.mybatis.expand;

import org.ala.tiktools.mybatis.expand.executor.SimpleExecutorExpander;
import org.ala.tiktools.mybatis.pager.PagerHandler;
import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.executor.*;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.transaction.Transaction;

/**
 * 扩展MyBatis的Configuration
 * - 重新定义MapperRegister，加上一些自己的前置逻辑
 *
 * @author ala
 * @date 2025-01-07 10:03
 */
public class ConfigurationExpander extends Configuration {

    /**
     * 可替换的mapperRegistry
     */
    protected MapperRegistryExpander mapperRegistry = new MapperRegistryExpander(this);
    /**
     * Method和MapperMethodExpander对应关系
     */
    protected MapperMethodHolder mapperMethodHolder = new MapperMethodHolder(this);
    /**
     * 分页Handler
     */
    protected PagerHandler pagerHandler = new PagerHandler();


    public ConfigurationExpander(Environment environment) {
        super();
    }
    public ConfigurationExpander() {
        super();
    }

    /**
     * Gets the mapper registry.
     *
     * @return the mapper registry
     *
     * @since 3.2.2
     */
    public MapperRegistryExpander getMapperRegistry() {
        return mapperRegistry;
    }
    public void setMapperRegistry(MapperRegistryExpander mapperRegistry) {
        this.mapperRegistry = mapperRegistry;
    }

    public void addMappers(String packageName, Class<?> superType) {
        mapperRegistry.addMappers(packageName, superType);
    }
    public void addMappers(String packageName) {
        mapperRegistry.addMappers(packageName);
    }
    public <T> void addMapper(Class<T> type) {
        mapperRegistry.addMapper(type);
    }
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
    }
    public boolean hasMapper(Class<?> type) {
        return mapperRegistry.hasMapper(type);
    }


    public MapperMethodHolder getMapperMethodHolder() {
        return mapperMethodHolder;
    }

    public PagerHandler getPagerHandler() {
        return pagerHandler;
    }

    public void setPagerHandler(PagerHandler pagerHandler) {
        this.pagerHandler = pagerHandler;
    }


    @Override
    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
            executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
            executor = new ReuseExecutor(this, transaction);
        } else {
//            executor = new SimpleExecutor(this, transaction);
            executor = new SimpleExecutorExpander(this, transaction);
        }
        if (cacheEnabled) {
            executor = new CachingExecutor(executor);
        }
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
    }


}
